/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */
#include "bsp.h"

typedef enum {
    FILTER_MODE_PASS,  // 通过模式，只接受指定ID
    FILTER_MODE_BLOCK  // 屏蔽模式，拒绝指定ID
} FilterMode;
typedef enum {
    FIFO_0,  // 分配到 FIFO0
    FIFO_1    // 分配到 FIFO1
} FifoAssignment;

/* USER CODE END 0 */

CAN_HandleTypeDef hcan;

/* CAN init function */
void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN;

  hcan.Init.Prescaler = 6;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_9TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = ENABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = ENABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */
  // 配置滤波器接受所有CAN帧
  //CAN_ConfigureFilter_AcceptAll(&hcan, 0, FIFO_0);
	
	// 只接收配置的CAN id
	hcan.Instance->FA1R = 0; // ���������˲�����	
	CAN_ConfigureFilter_Manual_32BitFilterMode(&hcan, 0x0B, 0, FILTER_MODE_BLOCK, FIFO_0);
	CAN_ConfigureFilter_Manual_32BitFilterMode(&hcan, 0x222, 1, FILTER_MODE_BLOCK, FIFO_0);
	CAN_ConfigureFilter_Manual_32BitFilterMode(&hcan, 0x333, 2, FILTER_MODE_BLOCK, FIFO_0);
  // 启动 CAN
  if (HAL_CAN_Start(&hcan) != HAL_OK)
  {
    Error_Handler();
  }

   // 激活接收中断
  if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE END CAN_Init 2 */
}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN)
  {
  /* USER CODE BEGIN CAN_MspInit 0 */

  /* USER CODE END CAN_MspInit 0 */
    /* CAN clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* CAN interrupt Init */
    HAL_NVIC_SetPriority(USB_HP_CAN_TX_IRQn, 8, 0);
    HAL_NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn);
    HAL_NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 9, 0);
    HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN_RX1_IRQn, 10, 0);
    HAL_NVIC_EnableIRQ(CAN_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN_SCE_IRQn, 15, 0);
    HAL_NVIC_EnableIRQ(CAN_SCE_IRQn);
  /* USER CODE BEGIN CAN_MspInit 1 */

  /* USER CODE END CAN_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN)
  {
  /* USER CODE BEGIN CAN_MspDeInit 0 */

  /* USER CODE END CAN_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();

    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* CAN interrupt Deinit */
    HAL_NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn);
    HAL_NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN_RX1_IRQn);
    HAL_NVIC_DisableIRQ(CAN_SCE_IRQn);
  /* USER CODE BEGIN CAN_MspDeInit 1 */

  /* USER CODE END CAN_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
void CAN_ConfigureFilter_Manual_16BitFilterMode(CAN_HandleTypeDef* hcan, uint32_t filter_id, uint8_t filter_bank, uint8_t filter_mode, uint8_t fifo)
{
    SET_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);
    CLEAR_BIT(hcan->Instance->FA1R, (1U << filter_bank));
    CLEAR_BIT(hcan->Instance->FS1R, (1U << filter_bank)); // 16 位模式
    CLEAR_BIT(hcan->Instance->FM1R, (1U << filter_bank)); // 掩码模式

    if (filter_mode == 1) // 通过模式
    {
        uint32_t filter_id_high = (filter_id << 5);  // 0x8AC0
        uint32_t filter_mask_high = (0x7FF << 5);    // 0xFFE0
        // ���� Filter 0 �� Filter 1 ��ͬ
//        hcan->Instance->sFilterRegister[filter_bank].FR1 = (filter_id_high << 16) | filter_id_high;   // 0x8AC08AC0
//        hcan->Instance->sFilterRegister[filter_bank].FR2 = (filter_mask_high << 16) | filter_mask_high; // 0xFFE0FFE0
			
				hcan->Instance->sFilterRegister[filter_bank].FR1 = (filter_id_high << 16); // ������ Filter 1
				hcan->Instance->sFilterRegister[filter_bank].FR2 = (filter_mask_high << 16);
    }
    else // �������� ID
    {
        hcan->Instance->sFilterRegister[filter_bank].FR1 = 0;
        hcan->Instance->sFilterRegister[filter_bank].FR2 = 0;
    }

    if (fifo == 0)
        CLEAR_BIT(hcan->Instance->FFA1R, (1U << filter_bank));
    else
        SET_BIT(hcan->Instance->FFA1R, (1U << filter_bank));

    SET_BIT(hcan->Instance->FA1R, (1U << filter_bank));
    CLEAR_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);

    SEGGER_RTT_CustomFunction(1, 0, "Manual FR1: 0x%08X\n", hcan->Instance->sFilterRegister[filter_bank].FR1);
    SEGGER_RTT_CustomFunction(1, 0, "Manual FR2: 0x%08X\n", hcan->Instance->sFilterRegister[filter_bank].FR2);
}

/**
 * @brief  �ֶ����� CAN �˲�����32 λģʽ��
 * @param  hcan: CAN �����ָ�� CAN ��������ýṹ
 * @param  filter_id: Ҫ���˻�ͨ���� CAN ID��11 λ��׼ ID �� 29 λ��չ ID��
 * @param  filter_bank: �˲������ţ���Χȡ���ھ��� MCU������ STM32F303xB/C Ϊ 0-27��
 * @param  filter_mode: �˲���ģʽ��FILTER_MODE_PASS ��ʾֻ����ָ�� ID��FILTER_MODE_BLOCK ��ʾ����ָ�� ID��
 * @param  fifo: ���䵽�ĸ� FIFO��FIFO_0 �� FIFO_1��
 * @retval None
 */
void CAN_ConfigureFilter_Manual_32BitFilterMode(CAN_HandleTypeDef* hcan, uint32_t filter_id, uint8_t filter_bank, uint8_t filter_mode, uint8_t fifo)
{
    SET_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);
    CLEAR_BIT(hcan->Instance->FA1R, (1U << filter_bank));
    SET_BIT(hcan->Instance->FS1R, (1U << filter_bank)); // 设置为 32 位模式
    CLEAR_BIT(hcan->Instance->FM1R, (1U << filter_bank));  // 掩码模式


    if (filter_mode == 1) // ͨ��ģʽ
    {
        uint32_t filter_id_full = (filter_id << 21);  // ��׼ ID ���� 21 λ��0x2C400000
        uint32_t filter_mask_full = (0x7FF << 21);    // ���룬0xFFE00000
        hcan->Instance->sFilterRegister[filter_bank].FR1 = filter_id_full;   // 0x2C400000
        hcan->Instance->sFilterRegister[filter_bank].FR2 = filter_mask_full; // 0xFFE00000
    }
    else
    {
        hcan->Instance->sFilterRegister[filter_bank].FR1 = 0;
        hcan->Instance->sFilterRegister[filter_bank].FR2 = 0;
    }

    if (fifo == 0)
        CLEAR_BIT(hcan->Instance->FFA1R, (1U << filter_bank));
    else
        SET_BIT(hcan->Instance->FFA1R, (1U << filter_bank));

    SET_BIT(hcan->Instance->FA1R, (1U << filter_bank));
    CLEAR_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);

    SEGGER_RTT_CustomFunction(1, 0, "Manual FR1: 0x%08X\n", hcan->Instance->sFilterRegister[filter_bank].FR1);
    SEGGER_RTT_CustomFunction(1, 0, "Manual FR2: 0x%08X\n", hcan->Instance->sFilterRegister[filter_bank].FR2);
}

// 新增函数：配置滤波器接受所有CAN标准帧
void CAN_ConfigureFilter_AcceptAll(CAN_HandleTypeDef* hcan, uint8_t filter_bank, uint8_t fifo)
{
    SET_BIT(hcan->Instance->FMR, CAN_FMR_FINIT); // 进入滤波器初始化模式
    CLEAR_BIT(hcan->Instance->FA1R, (1U << filter_bank)); // 禁用滤波器BANK
    SET_BIT(hcan->Instance->FS1R, (1U << filter_bank)); // 配置为32位模式
    CLEAR_BIT(hcan->Instance->FM1R, (1U << filter_bank)); // 配置为掩码模式

    // 设置FR1和FR2为0，接受所有ID
    hcan->Instance->sFilterRegister[filter_bank].FR1 = 0;
    hcan->Instance->sFilterRegister[filter_bank].FR2 = 0;

    // 配置FIFO分配
    if (fifo == 0)
        CLEAR_BIT(hcan->Instance->FFA1R, (1U << filter_bank)); // 分配到FIFO0
    else
        SET_BIT(hcan->Instance->FFA1R, (1U << filter_bank)); // 分配到FIFO1

    SET_BIT(hcan->Instance->FA1R, (1U << filter_bank)); // 启用滤波器BANK
    CLEAR_BIT(hcan->Instance->FMR, CAN_FMR_FINIT); // 退出滤波器初始化模式

    SEGGER_RTT_CustomFunction(1, 0, "Accept all filter configured for bank %d\n", filter_bank);
}
/* USER CODE END 1 */
